<template>
  <div class="min-h-screen py-8 px-4 sm:px-6 lg:px-8">
    <div class="max-w-7xl mx-auto">
      <!-- 页面标题 -->
      <div class="text-center mb-12">
        <h1 class="text-4xl font-bold mb-4 tech-text">WebCodecs API</h1>
        <p class="text-gray-300 text-lg">
          高性能音视频编解码，实现低延迟的媒体处理
        </p>
      </div>

      <!-- 浏览器支持提示 -->
      <div v-if="!isSupported" class="tech-card mb-8 border-yellow-600">
        <div class="flex items-center mb-4">
          <i class="i-carbon-warning text-yellow-500 text-xl mr-3"></i>
          <h3 class="text-xl font-semibold text-yellow-500">浏览器支持提示</h3>
        </div>
        <p class="text-gray-300">
          您的浏览器不支持 WebCodecs API。此功能需要 Chrome 94+、Edge 94+ 或其他支持的现代浏览器。
        </p>
      </div>

      <template v-if="isSupported">
        <!-- 视频编码器 -->
        <div class="tech-card mb-8">
          <div class="flex items-center mb-6">
            <i class="i-carbon-video text-3xl text-tech-accent mr-3"></i>
            <h2 class="text-2xl font-semibold text-white">视频编码器</h2>
          </div>

          <div class="space-y-6">
            <!-- 视频源选择 -->
            <div class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">选择视频源</h3>
              
              <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
                <div>
                  <input
                    ref="videoFileInput"
                    type="file"
                    accept="video/*"
                    @change="handleVideoFile"
                    class="hidden"
                  >
                  <button
                    @click="videoFileInput?.click()"
                    class="tech-button w-full"
                  >
                    <i class="i-carbon-document-add mr-2"></i>
                    上传视频文件
                  </button>
                </div>

                <button
                  @click="captureCamera"
                  class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-lg transition-colors"
                >
                  <i class="i-carbon-video-add mr-2"></i>
                  使用摄像头
                </button>
              </div>

              <div v-if="sourceVideo" class="mt-4">
                <video
                  ref="sourceVideoElement"
                  :src="sourceVideo"
                  controls
                  class="w-full max-h-64 bg-black rounded-lg"
                ></video>
              </div>
            </div>

            <!-- 编码设置 -->
            <div class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">编码设置</h3>

              <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                  <label class="block text-gray-300 mb-2">编码格式:</label>
                  <select
                    v-model="videoCodec"
                    class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2 focus:border-tech-accent outline-none"
                  >
                    <option value="vp8">VP8</option>
                    <option value="vp09.00.10.08">VP9</option>
                    <option value="avc1.42001E">H.264 (AVC)</option>
                    <option value="av01.0.05M.08">AV1</option>
                  </select>
                </div>

                <div>
                  <label class="block text-gray-300 mb-2">比特率: {{ videoBitrate / 1000 }} kbps</label>
                  <input
                    v-model.number="videoBitrate"
                    type="range"
                    min="100000"
                    max="5000000"
                    step="100000"
                    class="w-full"
                  >
                </div>

                <div>
                  <label class="block text-gray-300 mb-2">帧率: {{ videoFramerate }} fps</label>
                  <input
                    v-model.number="videoFramerate"
                    type="range"
                    min="10"
                    max="60"
                    step="5"
                    class="w-full"
                  >
                </div>

                <div>
                  <label class="block text-gray-300 mb-2">宽度: {{ videoWidth }}px</label>
                  <input
                    v-model.number="videoWidth"
                    type="range"
                    min="320"
                    max="1920"
                    step="160"
                    class="w-full"
                  >
                </div>
              </div>

              <div class="mt-6 flex gap-3">
                <button
                  @click="startVideoEncoding"
                  :disabled="!sourceVideo || isEncoding"
                  class="tech-button flex-1 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <i class="i-carbon-play-filled mr-2"></i>
                  {{ isEncoding ? '编码中...' : '开始编码' }}
                </button>

                <button
                  @click="stopVideoEncoding"
                  :disabled="!isEncoding"
                  class="bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <i class="i-carbon-stop-filled mr-2"></i>
                  停止
                </button>
              </div>
            </div>

            <!-- 编码统计 -->
            <div v-if="encodingStats.framesEncoded > 0" class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">编码统计</h3>

              <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
                <div class="text-center">
                  <div class="text-3xl font-bold text-blue-400">{{ encodingStats.framesEncoded }}</div>
                  <div class="text-gray-400 text-sm mt-1">已编码帧数</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-green-400">{{ encodingStats.keyFrames }}</div>
                  <div class="text-gray-400 text-sm mt-1">关键帧</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-purple-400">{{ formatBytes(encodingStats.totalBytes) }}</div>
                  <div class="text-gray-400 text-sm mt-1">数据大小</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-yellow-400">{{ encodingStats.duration.toFixed(2) }}s</div>
                  <div class="text-gray-400 text-sm mt-1">编码时长</div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 视频解码器 -->
        <div class="tech-card mb-8">
          <div class="flex items-center mb-6">
            <i class="i-carbon-play-outline text-3xl text-tech-accent mr-3"></i>
            <h2 class="text-2xl font-semibold text-white">视频解码器</h2>
          </div>

          <div class="space-y-6">
            <div class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">解码预览</h3>

              <canvas
                ref="decodedCanvas"
                width="640"
                height="480"
                class="w-full bg-black rounded-lg mb-4"
              ></canvas>

              <div class="flex gap-3">
                <button
                  @click="startVideoDecoding"
                  :disabled="!encodedChunks.length || isDecoding"
                  class="tech-button flex-1 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <i class="i-carbon-play-filled mr-2"></i>
                  {{ isDecoding ? '解码中...' : '开始解码' }}
                </button>

                <button
                  @click="stopVideoDecoding"
                  :disabled="!isDecoding"
                  class="bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <i class="i-carbon-stop-filled mr-2"></i>
                  停止
                </button>
              </div>
            </div>

            <!-- 解码统计 -->
            <div v-if="decodingStats.framesDecoded > 0" class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">解码统计</h3>

              <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
                <div class="text-center">
                  <div class="text-3xl font-bold text-blue-400">{{ decodingStats.framesDecoded }}</div>
                  <div class="text-gray-400 text-sm mt-1">已解码帧数</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-green-400">{{ decodingStats.fps }}</div>
                  <div class="text-gray-400 text-sm mt-1">当前帧率</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-purple-400">{{ decodingStats.droppedFrames }}</div>
                  <div class="text-gray-400 text-sm mt-1">丢帧数</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-yellow-400">{{ decodingStats.duration.toFixed(2) }}s</div>
                  <div class="text-gray-400 text-sm mt-1">解码时长</div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 音频编解码 -->
        <div class="tech-card mb-8">
          <div class="flex items-center mb-6">
            <i class="i-carbon-audio-console text-3xl text-tech-accent mr-3"></i>
            <h2 class="text-2xl font-semibold text-white">音频编解码</h2>
          </div>

          <div class="space-y-6">
            <!-- 音频源 -->
            <div class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">音频源</h3>

              <div class="flex gap-3 mb-4">
                <button
                  @click="generateTestTone"
                  class="tech-button flex-1"
                >
                  <i class="i-carbon-wave mr-2"></i>
                  生成测试音调
                </button>

                <button
                  @click="captureMicrophone"
                  class="bg-purple-600 hover:bg-purple-700 text-white px-6 py-3 rounded-lg transition-colors flex-1"
                >
                  <i class="i-carbon-microphone mr-2"></i>
                  使用麦克风
                </button>
              </div>

              <div v-if="hasAudioSource" class="bg-gray-900 rounded-lg p-4">
                <div class="flex items-center justify-between">
                  <span class="text-white">音频源已就绪</span>
                  <i class="i-carbon-checkmark-filled text-2xl text-green-400"></i>
                </div>
              </div>
            </div>

            <!-- 音频编码设置 -->
            <div class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">编码设置</h3>

              <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div>
                  <label class="block text-gray-300 mb-2">音频编码格式:</label>
                  <select
                    v-model="audioCodec"
                    class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2 focus:border-tech-accent outline-none"
                  >
                    <option value="opus">Opus</option>
                    <option value="mp4a.40.2">AAC</option>
                    <option value="pcm">PCM</option>
                  </select>
                </div>

                <div>
                  <label class="block text-gray-300 mb-2">采样率:</label>
                  <select
                    v-model.number="audioSampleRate"
                    class="w-full bg-gray-700 text-white border border-gray-600 rounded-lg px-3 py-2 focus:border-tech-accent outline-none"
                  >
                    <option :value="8000">8000 Hz</option>
                    <option :value="16000">16000 Hz</option>
                    <option :value="44100">44100 Hz</option>
                    <option :value="48000">48000 Hz</option>
                  </select>
                </div>
              </div>

              <div class="mt-6 flex gap-3">
                <button
                  @click="startAudioEncoding"
                  :disabled="!hasAudioSource || isAudioEncoding"
                  class="tech-button flex-1 disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <i class="i-carbon-play-filled mr-2"></i>
                  {{ isAudioEncoding ? '编码中...' : '开始音频编码' }}
                </button>

                <button
                  @click="stopAudioEncoding"
                  :disabled="!isAudioEncoding"
                  class="bg-red-600 hover:bg-red-700 text-white px-6 py-3 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                >
                  <i class="i-carbon-stop-filled mr-2"></i>
                  停止
                </button>
              </div>
            </div>

            <!-- 音频统计 -->
            <div v-if="audioStats.chunksEncoded > 0" class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">音频统计</h3>

              <div class="grid grid-cols-2 md:grid-cols-4 gap-4">
                <div class="text-center">
                  <div class="text-3xl font-bold text-blue-400">{{ audioStats.chunksEncoded }}</div>
                  <div class="text-gray-400 text-sm mt-1">编码块数</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-green-400">{{ formatBytes(audioStats.totalBytes) }}</div>
                  <div class="text-gray-400 text-sm mt-1">数据大小</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-purple-400">{{ audioStats.duration.toFixed(2) }}s</div>
                  <div class="text-gray-400 text-sm mt-1">编码时长</div>
                </div>

                <div class="text-center">
                  <div class="text-3xl font-bold text-yellow-400">{{ audioCodec }}</div>
                  <div class="text-gray-400 text-sm mt-1">编码格式</div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- 支持的编解码器 -->
        <div class="tech-card mb-8">
          <h2 class="text-2xl font-semibold mb-6 text-white">浏览器支持的编解码器</h2>

          <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
            <!-- 视频编解码器 -->
            <div class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">视频编解码器</h3>
              
              <div class="space-y-2">
                <div
                  v-for="codec in videoCodecSupport"
                  :key="codec.name"
                  class="flex items-center justify-between bg-gray-900 rounded-lg p-3"
                >
                  <span class="text-gray-300">{{ codec.name }}</span>
                  <span
                    :class="[
                      codec.supported ? 'text-green-400' : 'text-red-400'
                    ]"
                  >
                    {{ codec.supported ? '✓ 支持' : '✗ 不支持' }}
                  </span>
                </div>
              </div>
            </div>

            <!-- 音频编解码器 -->
            <div class="bg-gray-800 rounded-lg p-6">
              <h3 class="text-white font-semibold mb-4">音频编解码器</h3>
              
              <div class="space-y-2">
                <div
                  v-for="codec in audioCodecSupport"
                  :key="codec.name"
                  class="flex items-center justify-between bg-gray-900 rounded-lg p-3"
                >
                  <span class="text-gray-300">{{ codec.name }}</span>
                  <span
                    :class="[
                      codec.supported ? 'text-green-400' : 'text-red-400'
                    ]"
                  >
                    {{ codec.supported ? '✓ 支持' : '✗ 不支持' }}
                  </span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </template>

      <!-- API 信息 -->
      <div class="tech-card">
        <h3 class="text-xl font-semibold mb-4 text-white">API 信息</h3>
        <div class="space-y-4 text-gray-300">
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">浏览器支持</h4>
            <p>Chrome 94+, Edge 94+, Opera 80+</p>
            <p class="text-sm text-yellow-400 mt-1">注意：Firefox 和 Safari 目前不支持</p>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">核心 API</h4>
            <ul class="list-disc list-inside space-y-1">
              <li><code class="bg-gray-800 px-2 py-1 rounded">VideoEncoder</code> - 视频编码器</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">VideoDecoder</code> - 视频解码器</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">AudioEncoder</code> - 音频编码器</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">AudioDecoder</code> - 音频解码器</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">VideoFrame</code> - 视频帧</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">AudioData</code> - 音频数据</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">EncodedVideoChunk</code> - 编码后的视频块</li>
              <li><code class="bg-gray-800 px-2 py-1 rounded">EncodedAudioChunk</code> - 编码后的音频块</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">基本用法</h4>
            <pre class="bg-gray-800 p-4 rounded text-sm overflow-x-auto">
<span class="text-gray-500">// 创建视频编码器</span>
<span class="text-blue-400">const</span> encoder = <span class="text-blue-400">new</span> VideoEncoder({
  output: (chunk, metadata) => {
    <span class="text-gray-500">// 处理编码后的数据块</span>
    console.log(<span class="text-green-400">'Encoded chunk:'</span>, chunk);
  },
  error: (e) => {
    console.error(<span class="text-green-400">'Encoding error:'</span>, e);
  }
});

<span class="text-gray-500">// 配置编码器</span>
encoder.configure({
  codec: <span class="text-green-400">'vp8'</span>,
  width: <span class="text-orange-400">640</span>,
  height: <span class="text-orange-400">480</span>,
  bitrate: <span class="text-orange-400">1_000_000</span>,
  framerate: <span class="text-orange-400">30</span>
});

<span class="text-gray-500">// 编码视频帧</span>
<span class="text-blue-400">const</span> frame = <span class="text-blue-400">new</span> VideoFrame(videoElement, {
  timestamp: <span class="text-orange-400">0</span>
});
encoder.encode(frame, { keyFrame: <span class="text-blue-400">true</span> });
frame.close();</pre>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">支持的编解码器</h4>
            <div class="text-sm space-y-2">
              <p><strong>视频：</strong>VP8, VP9, H.264 (AVC), H.265 (HEVC), AV1</p>
              <p><strong>音频：</strong>Opus, AAC, MP3, PCM, Vorbis</p>
              <p class="text-xs text-gray-400">具体支持取决于浏览器实现和硬件加速</p>
            </div>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">使用场景</h4>
            <ul class="list-disc list-inside space-y-1 text-sm">
              <li>视频会议和实时通信应用</li>
              <li>视频编辑和转码工具</li>
              <li>屏幕录制和游戏直播</li>
              <li>视频播放器和流媒体应用</li>
              <li>WebRTC 和低延迟传输</li>
              <li>AI 视频处理和分析</li>
              <li>视频特效和滤镜处理</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">优势特性</h4>
            <ul class="list-disc list-inside space-y-1 text-sm">
              <li><strong>高性能：</strong>直接访问浏览器底层编解码器</li>
              <li><strong>低延迟：</strong>适合实时音视频应用</li>
              <li><strong>硬件加速：</strong>利用 GPU 加速编解码</li>
              <li><strong>精细控制：</strong>逐帧控制编解码参数</li>
              <li><strong>灵活性：</strong>支持多种编解码器格式</li>
              <li><strong>标准化：</strong>基于 Web 标准的 API</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">最佳实践</h4>
            <ul class="list-disc list-inside space-y-1 text-sm">
              <li>检查编解码器是否支持（isConfigSupported）</li>
              <li>及时释放 VideoFrame 和 AudioData 资源</li>
              <li>合理设置比特率和帧率参数</li>
              <li>处理编码错误和异常情况</li>
              <li>使用 Workers 避免阻塞主线程</li>
              <li>监控队列长度防止内存溢出</li>
              <li>优先使用硬件加速的编解码器</li>
            </ul>
          </div>
          <div>
            <h4 class="font-semibold text-tech-accent mb-2">与其他 API 对比</h4>
            <div class="text-sm space-y-2">
              <p><strong>WebCodecs vs MediaRecorder：</strong></p>
              <ul class="list-disc list-inside ml-4 space-y-1">
                <li>WebCodecs 提供更精细的控制</li>
                <li>WebCodecs 延迟更低</li>
                <li>MediaRecorder 更简单易用</li>
              </ul>
              <p class="mt-2"><strong>WebCodecs vs FFmpeg.wasm：</strong></p>
              <ul class="list-disc list-inside ml-4 space-y-1">
                <li>WebCodecs 性能更好（原生实现）</li>
                <li>FFmpeg.wasm 功能更全面</li>
                <li>WebCodecs 浏览器支持有限</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'

// 类型定义
interface EncodingStats {
  framesEncoded: number
  keyFrames: number
  totalBytes: number
  duration: number
}

interface DecodingStats {
  framesDecoded: number
  fps: number
  droppedFrames: number
  duration: number
}

interface AudioStats {
  chunksEncoded: number
  totalBytes: number
  duration: number
}

interface CodecSupport {
  name: string
  supported: boolean
}

// 响应式状态
const isSupported = ref(false)

// 视频编码
const videoFileInput = ref<HTMLInputElement | null>(null)
const sourceVideoElement = ref<HTMLVideoElement | null>(null)
const sourceVideo = ref('')
const videoCodec = ref('vp8')
const videoBitrate = ref(1000000)
const videoFramerate = ref(30)
const videoWidth = ref(640)
const isEncoding = ref(false)
const encodedChunks = ref<any[]>([])
const encodingStats = ref<EncodingStats>({
  framesEncoded: 0,
  keyFrames: 0,
  totalBytes: 0,
  duration: 0
})

let videoEncoder: VideoEncoder | null = null
let videoEncodingStartTime = 0

// 视频解码
const decodedCanvas = ref<HTMLCanvasElement | null>(null)
const isDecoding = ref(false)
const decodingStats = ref<DecodingStats>({
  framesDecoded: 0,
  fps: 0,
  droppedFrames: 0,
  duration: 0
})

let videoDecoder: VideoDecoder | null = null
let decodingStartTime = 0
let lastFrameTime = 0

// 音频编码
const hasAudioSource = ref(false)
const audioCodec = ref('opus')
const audioSampleRate = ref(48000)
const isAudioEncoding = ref(false)
const audioStats = ref<AudioStats>({
  chunksEncoded: 0,
  totalBytes: 0,
  duration: 0
})

let audioEncoder: AudioEncoder | null = null
let audioContext: AudioContext | null = null
let audioEncodingStartTime = 0

// 编解码器支持
const videoCodecSupport = ref<CodecSupport[]>([])
const audioCodecSupport = ref<CodecSupport[]>([])

// 初始化
onMounted(async () => {
  isSupported.value = !!(window.VideoEncoder && window.VideoDecoder && window.AudioEncoder && window.AudioDecoder)
  
  if (isSupported.value) {
    await checkCodecSupport()
  }
})

// 清理
onUnmounted(() => {
  stopVideoEncoding()
  stopVideoDecoding()
  stopAudioEncoding()
  
  if (audioContext) {
    audioContext.close()
  }
})

// 检查编解码器支持
const checkCodecSupport = async () => {
  const videoCodecs = [
    { name: 'VP8', config: { codec: 'vp8', width: 640, height: 480 } },
    { name: 'VP9', config: { codec: 'vp09.00.10.08', width: 640, height: 480 } },
    { name: 'H.264', config: { codec: 'avc1.42001E', width: 640, height: 480 } },
    { name: 'AV1', config: { codec: 'av01.0.05M.08', width: 640, height: 480 } }
  ]

  const audioCodecs = [
    { name: 'Opus', config: { codec: 'opus', sampleRate: 48000, numberOfChannels: 2 } },
    { name: 'AAC', config: { codec: 'mp4a.40.2', sampleRate: 48000, numberOfChannels: 2 } },
    { name: 'PCM', config: { codec: 'pcm', sampleRate: 48000, numberOfChannels: 2 } }
  ]

  for (const codec of videoCodecs) {
    try {
      const support = await VideoEncoder.isConfigSupported(codec.config as any)
      videoCodecSupport.value.push({
        name: codec.name,
        supported: !!support.supported
      })
    } catch {
      videoCodecSupport.value.push({
        name: codec.name,
        supported: false
      })
    }
  }

  for (const codec of audioCodecs) {
    try {
      const support = await AudioEncoder.isConfigSupported(codec.config as any)
      audioCodecSupport.value.push({
        name: codec.name,
        supported: !!support.supported
      })
    } catch {
      audioCodecSupport.value.push({
        name: codec.name,
        supported: false
      })
    }
  }
}

// 处理视频文件
const handleVideoFile = (event: Event) => {
  const input = event.target as HTMLInputElement
  const file = input.files?.[0]
  
  if (file) {
    sourceVideo.value = URL.createObjectURL(file)
  }
}

// 使用摄像头
const captureCamera = async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ video: true })
    if (sourceVideoElement.value) {
      sourceVideoElement.value.srcObject = stream
      sourceVideoElement.value.play()
      sourceVideo.value = 'camera'
    }
  } catch (error) {
    console.error('无法访问摄像头:', error)
    alert('无法访问摄像头，请检查权限设置')
  }
}

// 开始视频编码
const startVideoEncoding = async () => {
  if (!sourceVideoElement.value) return

  isEncoding.value = true
  encodedChunks.value = []
  encodingStats.value = {
    framesEncoded: 0,
    keyFrames: 0,
    totalBytes: 0,
    duration: 0
  }
  videoEncodingStartTime = performance.now()

  videoEncoder = new VideoEncoder({
    output: (chunk, metadata) => {
      encodedChunks.value.push({ chunk, metadata })
      encodingStats.value.framesEncoded++
      encodingStats.value.totalBytes += chunk.byteLength
      
      if (chunk.type === 'key') {
        encodingStats.value.keyFrames++
      }
      
      encodingStats.value.duration = (performance.now() - videoEncodingStartTime) / 1000
    },
    error: (error) => {
      console.error('视频编码错误:', error)
      isEncoding.value = false
    }
  })

  await videoEncoder.configure({
    codec: videoCodec.value,
    width: videoWidth.value,
    height: Math.round(videoWidth.value * 0.75),
    bitrate: videoBitrate.value,
    framerate: videoFramerate.value
  })

  // 模拟编码过程
  encodeFrames()
}

// 编码帧
const encodeFrames = () => {
  if (!isEncoding.value || !videoEncoder || !sourceVideoElement.value) return

  const timestamp = performance.now() * 1000
  const frame = new VideoFrame(sourceVideoElement.value, { timestamp })
  
  const keyFrame = encodingStats.value.framesEncoded % 30 === 0
  videoEncoder.encode(frame, { keyFrame })
  frame.close()

  if (isEncoding.value && encodingStats.value.framesEncoded < 100) {
    setTimeout(() => encodeFrames(), 1000 / videoFramerate.value)
  } else {
    stopVideoEncoding()
  }
}

// 停止视频编码
const stopVideoEncoding = () => {
  isEncoding.value = false
  
  if (videoEncoder) {
    videoEncoder.close()
    videoEncoder = null
  }
}

// 开始视频解码
const startVideoDecoding = async () => {
  if (!decodedCanvas.value || encodedChunks.value.length === 0) return

  isDecoding.value = true
  decodingStats.value = {
    framesDecoded: 0,
    fps: 0,
    droppedFrames: 0,
    duration: 0
  }
  decodingStartTime = performance.now()
  lastFrameTime = decodingStartTime

  const ctx = decodedCanvas.value.getContext('2d')

  videoDecoder = new VideoDecoder({
    output: (frame) => {
      if (ctx) {
        ctx.drawImage(frame, 0, 0, decodedCanvas.value!.width, decodedCanvas.value!.height)
      }
      
      decodingStats.value.framesDecoded++
      
      const currentTime = performance.now()
      const frameDuration = currentTime - lastFrameTime
      if (frameDuration > 0) {
        decodingStats.value.fps = Math.round(1000 / frameDuration)
      }
      lastFrameTime = currentTime
      
      decodingStats.value.duration = (currentTime - decodingStartTime) / 1000
      
      frame.close()
    },
    error: (error) => {
      console.error('视频解码错误:', error)
      isDecoding.value = false
    }
  })

  await videoDecoder.configure({
    codec: videoCodec.value
  })

  // 解码所有块
  for (const { chunk } of encodedChunks.value) {
    if (isDecoding.value) {
      videoDecoder.decode(chunk)
    }
  }

  await videoDecoder.flush()
  stopVideoDecoding()
}

// 停止视频解码
const stopVideoDecoding = () => {
  isDecoding.value = false
  
  if (videoDecoder) {
    videoDecoder.close()
    videoDecoder = null
  }
}

// 生成测试音调
const generateTestTone = () => {
  hasAudioSource.value = true
  
  if (!audioContext) {
    audioContext = new AudioContext({ sampleRate: audioSampleRate.value })
  }
}

// 使用麦克风
const captureMicrophone = async () => {
  try {
    await navigator.mediaDevices.getUserMedia({ audio: true })
    hasAudioSource.value = true
    
    if (!audioContext) {
      audioContext = new AudioContext({ sampleRate: audioSampleRate.value })
    }
  } catch (error) {
    console.error('无法访问麦克风:', error)
    alert('无法访问麦克风，请检查权限设置')
  }
}

// 开始音频编码
const startAudioEncoding = async () => {
  if (!audioContext) return

  isAudioEncoding.value = true
  audioStats.value = {
    chunksEncoded: 0,
    totalBytes: 0,
    duration: 0
  }
  audioEncodingStartTime = performance.now()

  audioEncoder = new AudioEncoder({
    output: (chunk) => {
      audioStats.value.chunksEncoded++
      audioStats.value.totalBytes += chunk.byteLength
      audioStats.value.duration = (performance.now() - audioEncodingStartTime) / 1000
    },
    error: (error) => {
      console.error('音频编码错误:', error)
      isAudioEncoding.value = false
    }
  })

  await audioEncoder.configure({
    codec: audioCodec.value,
    sampleRate: audioSampleRate.value,
    numberOfChannels: 2,
    bitrate: 128000
  })

  // 模拟音频编码
  setTimeout(() => {
    stopAudioEncoding()
  }, 5000)
}

// 停止音频编码
const stopAudioEncoding = () => {
  isAudioEncoding.value = false
  
  if (audioEncoder) {
    audioEncoder.close()
    audioEncoder = null
  }
}

// 格式化字节
const formatBytes = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}
</script>

<style scoped>
/* 自定义样式 */
input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
}

input[type="range"]::-webkit-slider-track {
  background: #374151;
  height: 0.5rem;
  border-radius: 0.25rem;
}

input[type="range"]::-moz-range-track {
  background: #374151;
  height: 0.5rem;
  border-radius: 0.25rem;
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: #3b82f6;
  cursor: pointer;
  margin-top: -0.375rem;
}

input[type="range"]::-moz-range-thumb {
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: #3b82f6;
  cursor: pointer;
  border: none;
}
</style>

